package com.zlsy.secondtime.deadlock;

import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhouliang
 * @date 2020/6/19 21:44
 * <p>
 * 用try lock 来避免死锁
 */
public class TryLockDeadLock implements Runnable {

    int flag = 1;

    static Lock lock1 = new ReentrantLock();
    static Lock lock2 = new ReentrantLock();
    private static final Random R = new Random();


    @Override
    public void run() {
        if (flag == 1) {
            try {
                for (int i = 0; i < 100; i++) {
                    if (lock1.tryLock(800, TimeUnit.MILLISECONDS)) {
                        TimeUnit.MILLISECONDS.sleep(R.nextInt(30));
                        if (lock2.tryLock(600, TimeUnit.MILLISECONDS)) {
                            TimeUnit.MILLISECONDS.sleep(R.nextInt(30));
                            System.out.println("线程1成功获取到锁1和锁2！");
                            lock1.unlock();
                            lock2.unlock();
                        } else {
                            System.err.println("线程1只拿到锁1！");
                            lock1.unlock();
                        }
                    } else {
                        System.err.println("锁1和锁2都没拿到！");
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if (flag == 2) {
            try {
                for (int i = 0; i < 100; i++) {
                    if (lock2.tryLock(3000, TimeUnit.MILLISECONDS)) {
                        TimeUnit.MILLISECONDS.sleep(R.nextInt(30));
                        if (lock1.tryLock(200, TimeUnit.MILLISECONDS)) {
                            TimeUnit.MILLISECONDS.sleep(R.nextInt(30));
                            System.out.println("线程2成功获取到锁1和锁2！");
                            lock1.unlock();
                            lock2.unlock();
                        } else {
                            System.err.println("线程2只拿到锁2！");
                            lock2.unlock();
                        }
                    } else {
                        System.err.println("锁1和锁2都没拿到！");
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) {
        TryLockDeadLock r1 = new TryLockDeadLock();
        TryLockDeadLock r2 = new TryLockDeadLock();
        r1.flag = 1;
        r2.flag = 2;

        Thread thread1 = new Thread(r1);
        Thread thread2 = new Thread(r1);

        thread1.start();
        thread2.start();
    }
}
